// ledArc.js
//
// Simulates a simple 64 led cirle each led capable of 15 levels of brightness
// 
// Written by JP Sykes - Nomeist.com
//
// Licensed under CC Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
//
// v 0.1
//

// inlets and outlets
inlets = 1;
outlets = 1;


// initialize LED state array
var leds = [];
clear();

// set up jsui defaults to 2d
sketch.default2d();

// initialize graphics
refresh();
draw();

/*-----------------------------------
// CRAZY CIRCLE PLOTTING MATH FUNCTIONS:
------------------------------------*/

function magicTrigFunctionX(pointRatio){
    return Math.cos(pointRatio*2*Math.PI);
}
function magicTrigFunctionY(pointRatio){
    return Math.sin(pointRatio*2*Math.PI);
}

/*-----------------------------------
// THE MAIN DRAWING UPDATE FUNCTION:
------------------------------------*/

function draw(){
    with(sketch){
        // set how the polygons are rendered
        glclearcolor(0,0,0,100); // set the clear color
        glclear(); // erase the background
        var i = 64;
        var centerX = 0;
        var centerY = 0;
        
        for(j=0;j<i;j++){
            // plot the circles on a circle
            var pointRatio = (j+16)/i;  // the +16 is needed to make 0 top (no idea why)
            var xSteps = magicTrigFunctionX(pointRatio);
            var ySteps = magicTrigFunctionY(pointRatio);
            var pointX = centerX + xSteps * .9;
            var pointY = centerY + ySteps * .9;
            //outlet(0, "count="+j+"pointx="+pointX+"pointy="+pointY);
            moveto(pointX, pointY);
            intensity = leds[j]/15;
            glcolor(1,1,0, intensity);
            circle(0.045); // draw the circle
        }
    }
}

/*-----------------------------------
// UTILITY FUNCTIONS:
------------------------------------*/

// bang -- draw and refresh display
function bang(){
    draw();
    refresh();
}

// clear -- wipe the state clean
function clear(){
  for(i=0; i<64; i++){
    leds[i]=0; // wipe the state
  }
  outlet(0, "clear"); // clear the router or matrix~ downstream
  bang(); // draw and refresh display
}


// onresize -- deal with a resized jsui box
function onresize(w,h){
    bang(); // draw and refresh display
}

/*-----------------------------------
// LED OSC HANDLING FUNCTIONS:
------------------------------------*/

function arcRingSet(led, intensity){
  leds[led] = intensity;
  bang();
}

function arcRingAll(intensity){
  for (i=0; i<=64; i++){
    //post(i);
    leds[i] = intensity;
  }
  bang();
}

function arcRingMap(ledArray){
   for (i=0; i<64; i++){
     leds[i] = ledArray[i] || 0;
   }
   bang();
}

function arcRingRange(start, end, intensity){
  // is the end smaller than the start
  // in which case we have a wrap around
  if(start > end){
    // take it from start to 64
    for (i=start; i<64; i++){
      leds[i] = intensity
    }
    // now start at 0 and go up to end
    for (j=0;j<=end-1;j++){
      leds[j] = intensity;
    }
  }else{
    // just loop from start to end
    for (i=start; i<=end; i++){
      leds[i] = intensity;
    } 
  }
  bang();
}

/*------ THAT'S ALL FOLKS ------*/